package com.cat.at.chat.component;

import com.alibaba.fastjson.JSON;
import com.cat.at.chat.config.SparkAIConfig;
import com.cat.at.chat.domain.SparkRequestDTO;
import com.cat.at.chat.domain.SparkResponseDTO;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import org.apache.catalina.valves.rewrite.RewriteCond;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.util.UriComponentsBuilder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Slf4j
public class SparkAiClient {

    @Autowired
    private SparkAIConfig sparkAiConfig;


    public WebSocket sendToMessage(String uid, List<SparkRequestDTO.MessageText> msgs, WebSocketListener listener) throws Exception {

        String authUrl = getAuthorizationUrl();
        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        // 将 https/http 连接替换为 ws/wss 连接
        String url = authUrl.replace("http://", "ws://").replace("https://", "wss://");
        Request request = new Request.Builder().url(url).build();
        // 建立 wss 连接

        WebSocket webSocket = okHttpClient.newWebSocket(request, listener);
        // 组装请求参数
        SparkRequestDTO requestDTO = new SparkRequestDTO();
        requestDTO.setHeader(new SparkRequestDTO.Header(sparkAiConfig.getAppId(), uid));
        requestDTO.setParameter(new SparkRequestDTO.Parameter(new SparkRequestDTO.Chat("generalv3", 0.5f, 2048)));
        requestDTO.setPayload(new SparkRequestDTO.Payload(new SparkRequestDTO.Message(msgs)));
        // 发送请求
        String reqMsg = JSON.toJSONString(requestDTO);
        log.info("发送ws报文:{}", reqMsg);
        webSocket.send(reqMsg);
        return webSocket;
    }


    public String getAuthorizationUrl() throws Exception {
        URL url = new URL(sparkAiConfig.getUrl());

        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());

        String tmp = "host: " + url.getHost() + "\n" + "date: " + date + "\n" + "GET " + url.getPath() + " HTTP/1.1";

        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(sparkAiConfig.getApiSecret().getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(tmp.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // 拼接
        String authorizationOrigin = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", sparkAiConfig.getApiKey(), "hmac-sha256", "host date request-line", sha);
        String authorization = Base64.getEncoder().encodeToString(authorizationOrigin.getBytes(StandardCharsets.UTF_8));

        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(sparkAiConfig.getUrl()).queryParam("authorization", authorization).queryParam("date", date).queryParam("host", url.getHost());
        return builder.build().encode().toString();
    }


}
